package com.lrkj.waitress.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.lrkj.common.constant.FeeConstants;
import com.lrkj.common.constant.OrgConstants;
import com.lrkj.common.constant.PropertyConstants;
import com.lrkj.common.core.domain.entity.OrgTree;
import com.lrkj.common.exception.BaseException;
import com.lrkj.common.utils.DateUtils;
import com.lrkj.common.utils.LrkjDateUtil;
import com.lrkj.common.utils.SecurityUtils;
import com.lrkj.common.utils.StringUtils;
import com.lrkj.common.utils.uuid.IdUtils;
import com.lrkj.framework.utils.NumberUtils;
import com.lrkj.framework.utils.SerialNumUtil;
import com.lrkj.payfee.domain.ChargeNorm;
import com.lrkj.payfee.domain.RoomNorm;
import com.lrkj.payfee.service.IChargeNormService;
import com.lrkj.payfee.service.IRoomNormService;
import com.lrkj.payfee.service.IRuleCostService;
import com.lrkj.property.domain.Community;
import com.lrkj.property.domain.Room;
import com.lrkj.property.mapper.RoomMapper;
import com.lrkj.property.service.ICommunityService;
import com.lrkj.property.service.IRoomService;
import com.lrkj.system.service.IOrgTreeService;
import com.lrkj.waitress.domain.CustomInfo;
import com.lrkj.waitress.domain.JoinRegister;
import com.lrkj.waitress.domain.RoomCustom;
import com.lrkj.waitress.mapper.CustomInfoMapper;
import com.lrkj.waitress.mapper.JoinRegisterMapper;
import com.lrkj.waitress.service.IJoinFileService;
import com.lrkj.waitress.service.IJoinRegisterService;
import com.lrkj.waitress.service.IRoomCustomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.stream.Collectors;

/**
 * 入伙登记Service业务层处理
 *
 * @author yajun_ren
 * @date 2022-03-17
 */
@Service
public class JoinRegisterServiceImpl implements IJoinRegisterService {
    @Autowired
    private JoinRegisterMapper joinRegisterMapper;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IOrgTreeService orgTreeService;

    @Autowired
    private ICommunityService communityService;

    @Autowired
    private IRoomCustomService roomCustomService;

    @Autowired
    private CustomInfoMapper customInfoMapper;

    @Autowired
    private IJoinFileService joinFileService;

    @Autowired
    private IRoomNormService roomNormService;

    @Autowired
    private IChargeNormService chargeNormService;

    @Autowired
    private IRuleCostService ruleCostService;

    @Autowired
    private RoomMapper roomMapper;


    /**
     * 查询入伙登记
     *
     * @param id 入伙登记ID
     * @return 入伙登记
     */
    @Override
    public JoinRegister selectJoinRegisterById(String id) {
        return joinRegisterMapper.selectJoinRegisterById(id);
    }

    /**
     * 查询入伙登记列表
     *
     * @param joinRegister 入伙登记
     * @return 入伙登记
     */
    @Override
    public List<JoinRegister> selectJoinRegisterList(JoinRegister joinRegister) {
        return joinRegisterMapper.selectJoinRegisterList(joinRegister);
    }

    /**
     * 新增入伙登记
     *
     * @param joinRegister 入伙登记
     * @return 结果
     */
    @Override
    @Transactional
    public int insertJoinRegister(JoinRegister joinRegister) {
        joinRegister.setId(IdUtils.simpleUUID());
        joinRegister.setCreateTime(DateUtils.getNowDate());
        joinRegister.setNo(this.getNo("RHD"));
        if (joinRegister.getStatus()==null){
            joinRegister.setStatus(PropertyConstants.join_register_10);
        }
        this.setInfo(joinRegister);
        return joinRegisterMapper.insertJoinRegister(joinRegister);
    }

    /**
     * 修改入伙登记
     *
     * @param joinRegister 入伙登记
     * @return 结果
     */
    @Override
    @Transactional
    public int updateJoinRegister(JoinRegister joinRegister) {
        joinRegister.setUpdateTime(DateUtils.getNowDate());
        this.setInfo(joinRegister);
        return joinRegisterMapper.updateJoinRegister(joinRegister);
    }

    //添加基础信息
    private void setInfo(JoinRegister bean) {
        if (StringUtils.isNotEmpty(bean.getRoomId())) {
            Room room = roomService.selectRoomById(bean.getRoomId());
            bean.setDeptId(room.getDeptId());
            bean.setCommunityId(room.getCommunityId());
            bean.setFloorId(room.getFloorId());
            bean.setAncestors(room.getAncestors() + "," + room.getId());
            this.checkCustom(bean, room);
            this.doSavaOrUpdateFiles(bean);
            this.updateRoomNorm(bean);
        } else {
            throw new BaseException("缺少关键参数,请联系系统管理员");
        }
    }

    private void doSavaOrUpdateFiles(JoinRegister bean) {
        joinFileService.deleteByJoinRegisterId(bean.getId());
        if (null != bean.getJoinFileList() && bean.getJoinFileList().size() > 0) {
            bean.getJoinFileList().stream().forEach(x -> {
                if (StringUtils.isEmpty(x.getFileId())) {
                    x.setFileId(IdUtils.simpleUUID());
                }
                x.setJoinRegisterId(bean.getId());
                x.setCreateBy(SecurityUtils.getUsername());
                x.setCreateTime(DateUtils.getNowDate());
            });
            joinFileService.doSaveList(bean.getJoinFileList());
        }
    }

    //更新房屋收费标准,计费开始时间
    private void updateRoomNorm(JoinRegister bean) {
        if (null != bean.getRoomNormList() && bean.getRoomNormList().size() > 0) {
            //获取当前小区所有收费标准
            Map<String, ChargeNorm> chargeNormMap = chargeNormService.getChargeNormMap(bean.getCommunityId());
            Community community = communityService.selectCommunityById(bean.getCommunityId());
            Date fiscalPeriod = DateUtil.parse(LrkjDateUtil.getMinMonthDate(community.getFiscalPeriod()+"-01"), "yyyy-MM-dd");
            //检查计费时间是否在当前账期
//            roomNormService.checkFiscalPeriod(bean.getRoomNormList(),bean.getCommunityId(),chargeNormMap);
            bean.getRoomNormList().stream().forEach(x -> {
                x.setStatus(FeeConstants.room_norm_status_10001);
                x.setDeliveryTime(LrkjDateUtil.addDay(x.getBeginChargeTime(), -1));
                x.setNextBeginChargeTime(x.getBeginChargeTime());//下一次开始收费时间
                //入住计算下一次生成费用开始时间--》结束时间
                if (chargeNormMap.containsKey(x.getNormId())) {
                    ChargeNorm chargeNorm = chargeNormMap.get(x.getNormId());
                    //自然周期
                    if (chargeNorm.getChargeGenerateType().equals(FeeConstants.charge_generate_type_10)) {
                        //x.setNextFinishChargetime(LrkjDateUtil.getLastMonthDay(x.getBeginChargeTime()));//下一次结束收费时间
                        //入住时下一次结束收费时间使用当前账期
                        x.setNextFinishChargetime(LrkjDateUtil.getLastMonthDay(fiscalPeriod));//下一次结束收费时间
                    } else if (chargeNorm.getChargeGenerateType().equals(FeeConstants.charge_generate_type_20)) {
                        long poorMonth = DateUtil.betweenMonth(x.getBeginChargeTime(), fiscalPeriod, true);
                        Date offPoorMonthDate = DateUtil.offsetMonth(x.getBeginChargeTime(), (int) poorMonth + 1);
                        //顺延周期
                        //x.setNextFinishChargetime(DateUtil.offsetDay(DateUtil.offsetMonth(x.getBeginChargeTime(), 1), -1));//下一次结束收费时间
                        x.setNextFinishChargetime(DateUtil.offsetDay(offPoorMonthDate, -1));//下一次结束收费时间
                    }
                }
                roomNormService.updateRoomNorm(x);
            });
        }
    }

    //检查更新客户信息
    private void checkCustom(JoinRegister joinRegister, Room room) {
        if (StringUtils.isNotEmpty(joinRegister.getCustomId())) {
            CustomInfo customInfo = customInfoMapper.selectCustomInfoById(joinRegister.getCustomId());
            //检查是否在一个小区
            if (customInfo.getCommunityId().equals(room.getCommunityId())) {
                customInfo.setCellPhoneNumber(joinRegister.getCellPhoneNumber());
                customInfo.setIdCard(joinRegister.getIdCard());
                customInfo.setBirthDate(joinRegister.getBirthDate());
                customInfo.setSex(joinRegister.getSex());
                customInfo.setCorporateName(joinRegister.getCorporateName());
                customInfo.setContactAddress(joinRegister.getContactAddress());
                customInfo.setLinkman(joinRegister.getLinkman());
                customInfo.setCustomHeadImg(joinRegister.getCustomHeadImg());
                customInfo.setCustomNo(IdUtils.generateId() + "");//客户号
                customInfoMapper.updateCustomInfo(customInfo);
            } else {
                //如果没有在同一个小区 重新创建一条用户信息
                this.savaCustomInfo(joinRegister, room);
            }
        } else {
            this.savaCustomInfo(joinRegister, room);
        }
    }

    private void savaCustomInfo(JoinRegister joinRegister, Room room) {
        String customId = IdUtils.simpleUUID();
        Community community = communityService.selectCommunityById(room.getCommunityId());
        CustomInfo customInfo = new CustomInfo();
        customInfo.setCustomId(customId);
        customInfo.setCustomType(joinRegister.getCustomType());
        customInfo.setCommunityId(room.getCommunityId());
        customInfo.setCustomName(joinRegister.getCustomName());
        customInfo.setDeptId(room.getDeptId());
        customInfo.setAncestors(community.getAncestors() + "," + community.getId());
        customInfo.setCellPhoneNumber(joinRegister.getCellPhoneNumber());
        customInfo.setIdCard(joinRegister.getIdCard());
        customInfo.setBirthDate(joinRegister.getBirthDate());
        customInfo.setSex(joinRegister.getSex());
        customInfo.setCorporateName(joinRegister.getCorporateName());
        customInfo.setContactAddress(joinRegister.getContactAddress());
        customInfo.setLinkman(joinRegister.getLinkman());
        customInfo.setCustomHeadImg(joinRegister.getCustomHeadImg());
        joinRegister.setCustomId(customId);//添加业主ID
        customInfoMapper.insertCustomInfo(customInfo);
    }

    public String getNo(String key) {
        int nextVal = SerialNumUtil.getInstance().nextInt(key);
        return key + NumberUtils.frontCompWithZore(nextVal, 7);
    }

    /**
     * 批量删除入伙登记
     *
     * @param ids 需要删除的入伙登记ID
     * @return 结果
     */
    @Override
    public int deleteJoinRegisterByIds(String[] ids) {
        return joinRegisterMapper.deleteJoinRegisterByIds(ids);
    }

    /**
     * 删除入伙登记信息
     *
     * @param id 入伙登记ID
     * @return 结果
     */
    @Override
    public int deleteJoinRegisterById(String id) {
        return joinRegisterMapper.deleteJoinRegisterById(id);
    }

    @Override
    @Transactional
    public int auditing(String id) {
        JoinRegister joinRegister = joinRegisterMapper.selectJoinRegisterById(id);
        if (!joinRegister.getStatus().equals(PropertyConstants.join_register_10)) {
            throw new BaseException("状态发生改变,请刷新页面重新尝试。");
        }
        //绑定房屋和业主关系
        //1、更新房屋业主信息
        Room room = roomService.selectRoomById(joinRegister.getRoomId());
        if (StringUtils.isNotEmpty(room.getOwnerId())) {
            throw new BaseException("房屋【" + room.getRoomName() + "】已经入住了业主,请到房产管理,迁出房屋业主之后,在添加新的业主!");
        }
        room.setOwnerId(joinRegister.getCustomId());
        room.setStatusCd("1002");
        room.setState("10002");
        room.setUpdateBy(SecurityUtils.getUsername());
        room.setUpdateTime(DateUtils.getNowDate());
        roomService.updateRoom(room);
        //2、更新 组织树  房屋业主信息
        orgTreeService.insertOrgTree(room.getId(), room.getRoomNum(), room.getUnitId(), OrgConstants.room, room.getAncestors(), joinRegister.getCustomName());
        //3、添加房屋业主关系表记录
        RoomCustom roomCustom = new RoomCustom(room.getId(), joinRegister.getCustomId(), PropertyConstants.relation_type_10, PropertyConstants.owner_type_cd_1001);
        roomCustomService.insertRoomCustom(roomCustom);
        //更新入伙单信息
        joinRegister.setStatus(PropertyConstants.join_register_20);
        joinRegister.setUpdateBy(SecurityUtils.getUsername());
        joinRegister.setUpdateTime(DateUtils.getNowDate());
        return joinRegisterMapper.updateJoinRegister(joinRegister);
    }

    @Override
    public JoinRegister selectJoinByRoomId(JoinRegister joinRegisters) {
        return joinRegisterMapper.selectJoinByRoomId(joinRegisters);
    }

    /**
     * 迁出
     * @param joinRegisters
     * @return
     */
    @Override
    @Transactional
    public int emigrationAud(JoinRegister joinRegisters) {

        int count = ruleCostService.arrearageCountByRoomId(joinRegisters.getRoomId());
        if (count>0){
            throw new BaseException("该房间存在未交费的费用，请缴费后迁出");
        }
        //todo 修改房间收费标准为不收费
        RoomNorm roomNorm=new RoomNorm();
        roomNorm.setRoomId(joinRegisters.getRoomId());
        roomNorm.setStatus(FeeConstants.room_norm_status_10002);
        roomNormService.updteByRoomId(roomNorm);

        //todo 修改组织树 清空客户名称
        OrgTree orgTree=new OrgTree();
        orgTree.setId(joinRegisters.getRoomId());
        orgTree.setOwnerName("");
        orgTreeService.updateOrgTree(orgTree);

        //todo 删除绑定客户房间
        roomCustomService.deleteRoomCustomById(joinRegisters.getRoomId());

        //todo 修改房间状态
        Room room=new Room();
        room.setId(joinRegisters.getRoomId());
        room.setState("10001");
        room.setStatusCd("1001");
        roomMapper.updateRoomState(room);

        //todo 删除入伙数据
        int row = joinRegisterMapper.deleteJoinRegisterById(joinRegisters.getId());
        return row;
    }

    /**
     * 批量新增入伙登记信息
     *
     * @param joinRegisters 入伙登记对象
     */
    public int batchAddData(List<JoinRegister> joinRegisters) {
        return joinRegisterMapper.batchAddData(joinRegisters);
    }
}
